home *** CD-ROM | disk | FTP | other *** search
/ Aminet 25 / Aminet 25 (1998)(GTI - Schatztruhe)[!][Jun 1998].iso / Aminet / dev / misc / BoulderEngine.lha / BOULDER_feb_12.lha / MUSICKERNEL.C < prev    next >
Encoding:
C/C++ Source or Header  |  1980-01-01  |  9.5 KB  |  310 lines

  1.  
  2. #include "exec/types.h"
  3. #include "exec/memory.h"
  4. #include "devices/audio.h"
  5. #include "stdio.h"
  6.  
  7. #define  PRIORITY          10L    /* Priority for Audio Channel usage */
  8. #define  NBR_IOA_STRUCTS   10L    /* Number of IOAudio structures used */
  9. #define  PV_IOA_STRUCT     0L     /* index to ioapv struct */
  10. #define  FIN_IOA_STRUCT    9L     /* index to finishioa struct */
  11. #define  BIG_WAVE          256L   /* size of biggest waveform */
  12. #define  NBR_WAVES         7L     /* number of waves per instrument */
  13. #define  WAVES_TOTAL       1024L  /* alloc size for instrument's waves */
  14. #define  YES               1L
  15. #define  NO                0L
  16.  
  17. extern struct MsgPort *CreatePort();
  18. extern void *AllocMem();
  19.  
  20. UBYTE aMap[] = { 0x0f };                  /* allocate four channels */
  21. long  voiceMap[] = { 1, 2, 4, 8 };
  22. struct IOAudio *ioa, *finishioa, *ioapv;
  23. struct IOAudio *ioainuse[4];
  24. struct IOAudio *freeioa[4];
  25. long unitno = 1;
  26. int error;
  27. int waiting[4] = { NO, NO, NO, NO };
  28. int woffsets[] =
  29.    { 0, 256, 384, 448, 480, 496, 504, 508, 510 };
  30. int wlen[] =
  31.    { 256, 128, 64, 32, 16, 8, 4, 2, 1 };
  32. int perval[] =
  33.    { 428, 404, 381, 360, 339, 320, 302, 285, 269, 254, 240, 226, 214 };
  34. BYTE *wptr,*wptr2;
  35. BYTE *owptr[4] = { NULL, NULL, NULL, NULL };
  36.  
  37. char *portstring[] = {
  38.    "Audio one",
  39.    "Audio two",
  40.    "Audio three",
  41.    "Audio four",
  42.    "Audio five",
  43.    "Audio six",
  44.    "Audio seven",
  45.    "Audio eight" };              /* names for the CreatePorts */
  46.  
  47. STATIC BYTE Wave[]={
  48.  0 , 3 , 8 , 12 , 16 , 13 , 20 , 23 , 21 , 39 , 38 , 38 , 51 , 39 , 58 ,
  49.  61 , 53 , 56 , 62 , 65 , 69 , 69 , 64 , 63 , 60 , 78 , 74 , 73 , 64 , 84 , 79 ,
  50.  81 , 86 , 85 , 78 , 83 , 79 , 84 , 80 , 84 , 86 , 88 , 86 , 87 , 90 , 91 , 96 ,
  51.  98 , 103 , 97 , 100 , 102 , 109 , 100 , 101 , 115 , 115 , 117 , 124 , 106 , 114 , 113 , 103 ,
  52.  114 , 118 , 105 , 109 , 106 , 115 , 121 , 102 , 98 , 99 , 101 , 112 , 107 , 113 , 105 , 102 ,
  53.  103 , 97 , 92 , 92 , 93 , 91 , 87 , 86 , 87 , 86 , 88 , 81 , 90 , 85 , 85 , 86 ,
  54.  89 , 78 , 74 , 68 , 74 , 70 , 77 , 62 , 62 , 63 , 68 , 77 , 61 , 50 , 61 , 53 ,
  55.  54 , 56 , 61 , 43 , 36 , 39 , 46 , 40 , 27 , 27 , 19 , 27 , 21 , 13 , 12 , 7 ,
  56.  3 , 0 ,-1 ,-4 ,-7 ,-7 ,-9 ,-10 ,-8 ,-6 ,-21 ,-11 ,-14 ,-15 ,-14 ,-16 ,
  57. -13 ,-31 ,-17 ,-32 ,-21 ,-34 ,-47 ,-40 ,-26 ,-54 ,-38 ,-47 ,-57 ,-60 ,-57 ,-62 ,
  58. -68 ,-65 ,-71 ,-73 ,-65 ,-76 ,-72 ,-76 ,-81 ,-81 ,-82 ,-86 ,-87 ,-87 ,-86 ,-84 ,
  59. -86 ,-82 ,-82 ,-90 ,-78 ,-93 ,-86 ,-88 ,-84 ,-98 ,-86 ,-87 ,-93 ,-72 ,-71 ,-99 ,
  60. -87 ,-80 ,-73 ,-95 ,-87 ,-83 ,-75 ,-84 ,-84 ,-84 ,-77 ,-78 ,-96 ,-91 ,-80 ,-85 ,
  61. -86 ,-90 ,-92 ,-91 ,-85 ,-87 ,-87 ,-86 ,-82 ,-79 ,-78 ,-73 ,-76 ,-78 ,-73 ,-68 ,
  62. -65 ,-58 ,-60 ,-55 ,-49 ,-40 ,-41 ,-53 ,-40 ,-53 ,-48 ,-50 ,-25 ,-25 ,-17 ,-42 ,
  63. -26 ,-11 ,-26 ,-21 ,-32 ,-27 ,-18 ,-17 ,-6 ,-12 ,-4 ,-8 ,-6 ,-7 ,-5 ,-2 ,
  64. -1 };
  65. /* Sin Wave */
  66. STATIC BYTE Wave2[]={
  67.  0 , 3 , 6 , 9 , 12 , 15 , 18 , 21 , 24 , 27 , 30 , 33 , 36 , 39 , 42 ,
  68.  45 , 48 , 51 , 53 , 56 , 59 , 62 , 64 , 67 , 70 , 72 , 75 , 77 , 79 , 82 , 84 ,
  69.  86 , 89 , 91 , 93 , 95 , 97 , 99 , 101 , 103 , 104 , 106 , 108 , 109 , 111 , 112 , 113 ,
  70.  115 , 116 , 117 , 118 , 119 , 120 , 121 , 122 , 122 , 123 , 124 , 124 , 125 , 125 , 125 , 125 ,
  71.  125 , 126 , 125 , 125 , 125 , 125 , 125 , 124 , 124 , 123 , 122 , 122 , 121 , 120 , 119 , 118 ,
  72.  117 , 116 , 115 , 113 , 112 , 111 , 109 , 108 , 106 , 104 , 103 , 101 , 99 , 97 , 95 , 93 ,
  73.  91 , 89 , 86 , 84 , 82 , 79 , 77 , 75 , 72 , 70 , 67 , 64 , 62 , 59 , 56 , 53 ,
  74.  51 , 48 , 45 , 42 , 39 , 36 , 33 , 30 , 27 , 24 , 21 , 18 , 15 , 12 , 9 , 6 ,
  75.  3 , 0 ,-4 ,-7 ,-10 ,-13 ,-16 ,-19 ,-22 ,-25 ,-28 ,-31 ,-34 ,-37 ,-40 ,-43 ,
  76. -46 ,-49 ,-52 ,-54 ,-57 ,-60 ,-63 ,-65 ,-68 ,-71 ,-73 ,-76 ,-78 ,-80 ,-83 ,-85 ,
  77. -87 ,-90 ,-92 ,-94 ,-96 ,-98 ,-100 ,-102 ,-104 ,-105 ,-107 ,-109 ,-110 ,-112 ,-113 ,-114 ,
  78. -116 ,-117 ,-118 ,-119 ,-120 ,-121 ,-122 ,-123 ,-123 ,-124 ,-125 ,-125 ,-126 ,-126 ,-126 ,-126 ,
  79. -126 ,-126 ,-126 ,-126 ,-126 ,-126 ,-126 ,-125 ,-125 ,-124 ,-123 ,-123 ,-122 ,-121 ,-120 ,-119 ,
  80. -118 ,-117 ,-116 ,-114 ,-113 ,-112 ,-110 ,-109 ,-107 ,-105 ,-104 ,-102 ,-100 ,-98 ,-96 ,-94 ,
  81. -92 ,-90 ,-87 ,-85 ,-83 ,-80 ,-78 ,-76 ,-73 ,-71 ,-68 ,-65 ,-63 ,-60 ,-57 ,-54 ,
  82. -52 ,-49 ,-46 ,-43 ,-40 ,-37 ,-34 ,-31 ,-28 ,-25 ,-22 ,-19 ,-16 ,-13 ,-10 ,-7 ,
  83. -4 };
  84.  
  85. InitIOA()
  86.    {
  87.    int i;
  88.    ioa = (struct IOAudio *)AllocMem((NBR_IOA_STRUCTS * (long)sizeof(*ioa)),
  89.       MEMF_PUBLIC | MEMF_CLEAR);
  90.    if (ioa == NULL)
  91.       FinishProg(1);
  92.    for (i = 0; i < 4; ++i)
  93.       {
  94.       ioainuse[i] = &ioa[i + 1];
  95.       freeioa[i] = &ioa[i + 5];
  96.       }
  97.    ioapv = &ioa[PV_IOA_STRUCT];
  98.    finishioa = &ioa[FIN_IOA_STRUCT];
  99.    ioa->ioa_Request.io_Message.mn_Node.ln_Pri = PRIORITY;
  100.    ioa->ioa_Request.io_Message.mn_ReplyPort =
  101.       CreatePort("Audio zero", 0L);
  102.    if (ioa->ioa_Request.io_Message.mn_ReplyPort == NULL)
  103.       FinishProg(2);
  104.    ioa->ioa_Data = aMap;
  105.    ioa->ioa_Length = (long)sizeof(aMap);
  106.    error = OpenDevice(AUDIONAME, 0L, ioa, 0L);
  107.    if (error)
  108.       FinishProg(3);
  109.    *finishioa = *ioa;
  110.    finishioa->ioa_Request.io_Flags = IOF_QUICK;
  111.    ioapv->ioa_Request.io_Flags = IOF_QUICK;
  112.  
  113.    finishioa->ioa_Request.io_Command = ADCMD_FINISH;
  114.    ioapv->ioa_Request.io_Command = ADCMD_PERVOL;
  115.    for (i = 0; i < 4; ++i)
  116.       {
  117.       *freeioa[i] = *ioa;
  118.       *ioainuse[i] = *ioa;
  119.       freeioa[i]->ioa_Request.io_Message.mn_ReplyPort =
  120.          CreatePort(portstring[i], 0L);
  121.       ioainuse[i]->ioa_Request.io_Message.mn_ReplyPort =
  122.          CreatePort(portstring[i + 4], 0L);
  123.       }
  124.    for (i = 0; i < 4; ++i)
  125.       if (freeioa[i]->ioa_Request.io_Message.mn_ReplyPort == NULL ||
  126.          ioainuse[i]->ioa_Request.io_Message.mn_ReplyPort == NULL)
  127.          FinishProg(4);
  128.    }
  129. char *errormsgs[] = {
  130.    "Finished!\n",
  131.    "Cannot allocate memory for IOAudio structures\n",
  132.    "Cannot create ReplyPort for OpenDevice call\n",
  133.    "Cannot open Audio Device\n",
  134.    "Cannot create ReplyPort(s) for remaining IOAudio structures\n",
  135.    "Cannot allocate memory for waveform\n",
  136.    "If you see this during execution, execute the programmer.\n" };
  137.  
  138. FinishProg(finishcode)
  139.    int finishcode;
  140.    {
  141.    int i;
  142.  
  143.    printf(errormsgs[finishcode]);
  144.    switch(finishcode)
  145.       {
  146.    case 0:
  147.       /* free up the WaveNode list
  148.        * (currently, just wptr)
  149.        */
  150.       FreeMem(wptr, WAVES_TOTAL);
  151.       FreeMem(wptr2, WAVES_TOTAL);
  152.    case 4:
  153.    case 5:
  154.       for (i = 0; i < 4; ++i)
  155.          {
  156.          if (freeioa[i]->ioa_Request.io_Message.mn_ReplyPort)
  157.             DeletePort(freeioa[i]->ioa_Request.io_Message.mn_ReplyPort);
  158.          if (ioainuse[i]->ioa_Request.io_Message.mn_ReplyPort)
  159.             DeletePort(ioainuse[i]->ioa_Request.io_Message.mn_ReplyPort);
  160.          }
  161.       CloseDevice(ioa);
  162.  
  163.    case 3:
  164.       DeletePort(ioa->ioa_Request.io_Message.mn_ReplyPort);
  165.  
  166.    case 2:
  167.       FreeMem(ioa, (NBR_IOA_STRUCTS * (long)sizeof(*ioa)));
  168.  
  169.       }
  170.    if (finishcode)
  171.       exit(1L);
  172.    exit(0L);
  173.    }
  174.  
  175. setwpv(wf, len, per, vol, voice)
  176.    char *wf;
  177.    int len, per, vol, voice;
  178.    {
  179.    struct IOAudio *tmpioa;
  180.    freeioa[voice]->ioa_Request.io_Command = CMD_WRITE;
  181.    freeioa[voice]->ioa_Request.io_Flags = ADIOF_PERVOL | IOF_QUICK;
  182.    freeioa[voice]->ioa_Cycles = 0;
  183.    freeioa[voice]->ioa_Request.io_Unit = (struct Unit *)unitno;
  184.    finishioa->ioa_Request.io_Unit = (struct Unit *)unitno;
  185.    freeioa[voice]->ioa_Data = (UBYTE *)wf;
  186.    freeioa[voice]->ioa_Length = len;
  187.    freeioa[voice]->ioa_Period = per;
  188.    freeioa[voice]->ioa_Volume = vol;
  189.    if (waiting[voice])
  190.       {
  191.       BeginIO(finishioa);
  192.       WaitIO(ioainuse[voice]);
  193.       waiting[voice] = NO;
  194.       }
  195.  
  196.    /* now start up the new voice
  197.     */
  198.    BeginIO(freeioa[voice]);
  199.    error = CheckIO(freeioa[voice]);
  200.    if (error)
  201.       {
  202.       printf("Error on CMD_WRITE\n");
  203.       WaitIO(freeioa[voice]);
  204.       }
  205.    waiting[voice] = YES;
  206.    tmpioa = ioainuse[voice];
  207.    ioainuse[voice] = freeioa[voice];
  208.    freeioa[voice] = tmpioa;
  209.    }
  210.  
  211. setpv(per, vol)
  212.    int per, vol;
  213.    {
  214.    ioapv->ioa_Period = per;
  215.    ioapv->ioa_Volume = vol;
  216.    ioapv->ioa_Request.io_Unit = (struct Unit *)unitno;
  217.    BeginIO(ioapv);
  218.    }
  219. StopVoices()
  220.    {
  221.    int voice;
  222.  
  223.    for (voice = 0; voice < 4; ++voice)
  224.       {
  225.       if (waiting[voice])
  226.          {
  227.          unitno = voiceMap[voice];
  228.          setpv(128, 0);
  229.          finishioa->ioa_Request.io_Unit = (struct Unit *)unitno;
  230.          BeginIO(finishioa);
  231.          WaitIO(ioainuse[voice]);
  232.          waiting[voice] = NO;
  233.          }
  234.       }
  235.    }
  236.  
  237. setwave2(wfp)
  238. BYTE *wfp;
  239.   {
  240.    int i;
  241.    for(i=0;i<BIG_WAVE;++i) { wfp[i]=Wave2[i]; }
  242.   }
  243.  
  244. setwave(wfp)
  245.    BYTE *wfp;
  246.    {
  247.    int i;
  248.    for(i=0;i<BIG_WAVE;++i)
  249.     {
  250.       wfp[i]=Wave[i];
  251.     }
  252. xpandwave(wfp)
  253.    BYTE *wfp;
  254.    {
  255.    int i, j, rate;
  256.    BYTE *tptr;
  257.  
  258.    rate = 1;
  259.    tptr = wfp + BIG_WAVE;
  260.    for (i = 0; i < NBR_WAVES - 1; ++i)
  261.       {
  262.       rate *= 2;
  263.       for (j = 0; j < BIG_WAVE; j += rate)
  264.          *tptr++ = wfp[j];
  265.       }
  266.    }
  267.  
  268. makewaves()
  269.    {
  270.    /* allocate the memory for the waveform.
  271.     */
  272.    wptr = (BYTE *)AllocMem(WAVES_TOTAL, MEMF_CHIP);
  273.    if (wptr == NULL)
  274.       FinishProg(5);
  275.    setwave(wptr);
  276.    xpandwave(wptr);
  277.    wptr2 = (BYTE *)AllocMem(WAVES_TOTAL, MEMF_CHIP);
  278.    if (wptr == NULL)
  279.       FinishProg(5);
  280.    setwave2(wptr2);
  281.    xpandwave(wptr2);
  282.    }
  283.  
  284. strike(note, voice)
  285.    int note, voice;
  286.    {
  287.    int per, oct, len;
  288.    BYTE *wfp;
  289.  
  290.    unitno = voiceMap[voice];
  291.    if (note >= 100)           /* play a rest. */
  292.       {
  293.       if (waiting[voice])
  294.          setpv(200, 0);
  295.       return;
  296.       }
  297.    oct = note / 12;
  298.    per = perval[note % 12];
  299.    wfp = wptr + woffsets[oct];
  300.    if (wfp == owptr[voice])
  301.       setpv(per, 32);         /* fixed volume */
  302.    else
  303.       {
  304.       setwpv(wfp, wlen[oct], per, 32, voice);
  305.       owptr[voice] = wfp;
  306.       }
  307.    }
  308.  
  309.